package com.ecoolex.discount.sales.core.manager;

import java.sql.Date;
import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ecoolex.discount.sales.core.dao.YWStoreCateDAO;
import com.ecoolex.discount.sales.core.dao.YWStoreDAO;
import com.ecoolex.discount.sales.core.external.v2.pojo.GetStoresResponse;
import com.ecoolex.discount.sales.entity.YWStore;
import com.ecoolex.discount.sales.entity.YWStoreCate;
import com.ecoolex.discount.sales.entity.YWStoreCateExample;
import com.ecoolex.discount.sales.entity.YWStoreExample;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class YWStoreManager {
    @Autowired
    private YWStoreDAO dao;

    @Autowired
    private YWStoreCateDAO cateDAO;

    public void save(GetStoresResponse.Store store) {
        String storeId = store.getStoreId();
        String channelId = store.getChannelId();
        YWStoreExample.Criteria criteria = YWStoreExample.newAndCreateCriteria().andChannelIdEqualTo(channelId).andStoreIdEqualTo(storeId);
        YWStore ywStore = dao.selectOneByExample(criteria.example());
        if (Objects.nonNull(ywStore)) {
            BeanUtils.copyProperties(store, ywStore);
            ywStore.setStoreId(storeId);
            if( 0 < store.getUpdateTime()){
                ywStore.setLastModifiedTime(Date.from(Instant.ofEpochSecond(store.getUpdateTime())));
            }
            ywStore.setUpdateUser("system-admin");
            ywStore.setUpdateTime(Date.from(Instant.now()));
            dao.updateByPrimaryKey(ywStore);
            detectCategroyChange(store.getCategories(),storeId,channelId);
        } else {
            ywStore = new YWStore();
            BeanUtils.copyProperties(store, ywStore);
            ywStore.setStoreId(storeId);
            if(0 < store.getUpdateTime()){
                ywStore.setLastModifiedTime(Date.from(Instant.ofEpochSecond(store.getUpdateTime())));
            }
            ywStore.setStatus(1);
            ywStore.setDeleted(YWStore.NOT_DELETED);
            ywStore.setCreateTime(Date.from(Instant.now()));
            ywStore.setCreateUser("system-admin");
            ywStore.setUpdateUser("system-admin");
            ywStore.setUpdateTime(Date.from(Instant.now()));
            dao.insert(ywStore);
            if (!CollectionUtils.isEmpty(store.getCategories())) {
                List<YWStoreCate> StoreCateSet = store.getCategories().stream().map(item -> wrap(item,storeId,channelId)).collect(Collectors.toList());
                cateDAO.batchInsert(StoreCateSet);
            }

        }
    }

    private YWStoreCate wrap(String cate, String storeId,String channelId){
        YWStoreCate ywStoreCate = new YWStoreCate();
        ywStoreCate.setStoreId(storeId);
        ywStoreCate.setChannelId(channelId);
        ywStoreCate.setCategroy(cate);
        ywStoreCate.setStatus(1);
        ywStoreCate.setDeleted(YWStoreCate.NOT_DELETED);
        ywStoreCate.setCreateTime(Date.from(Instant.now()));
        ywStoreCate.setCreateUser("system-admin");
        ywStoreCate.setUpdateUser("system-admin");
        ywStoreCate.setUpdateTime(Date.from(Instant.now()));
        return ywStoreCate;
    }

    /**
     * 检测品牌类别的差异变化
     * @param category
     * @param storeId
     */
    public void detectCategroyChange(List<String> category,String storeId,String channelId){
        YWStoreCateExample.Criteria criteria = YWStoreCateExample.newAndCreateCriteria().andStoreIdEqualTo(storeId);
        List<YWStoreCate> cateList = cateDAO.selectByExample(criteria.example());
        if (CollectionUtils.isEmpty(category)
                && CollectionUtils.isEmpty(cateList)){ //待更新的与已持久化的都为空时，不执行任何操作
            log.info("Store:{} category is empty",storeId);
        }else {
            if (CollectionUtils.isEmpty(category)
                    && CollectionUtils.isNotEmpty(cateList)){ // 待更新的为空、已持久化的不为空时，则已持久化的全部标记为逻辑删除
                cateList.stream().filter(cate -> YWStoreCate.NOT_DELETED.equals(cate.getDeleted())).forEach(cate ->{
                    cate.setDeleted(YWStoreCate.IS_DELETED);
                    cateDAO.updateByPrimaryKeySelective(cate,YWStoreCate.Column.deleted);
                });
            }else if (CollectionUtils.isNotEmpty(category)
                    && CollectionUtils.isEmpty(cateList)){ // 待更新的为不为空、已持久化的空时，则待更新的全部插入
                List<YWStoreCate> brandCateSet = category.stream().distinct().map(item -> wrap(item,storeId,channelId)).collect(Collectors.toList());
                cateDAO.batchInsert(brandCateSet);
            }else {
                Map<String,YWStoreCate> cateMap = new HashMap<>(cateList.size());
                cateList.forEach(cate ->{
                    cateMap.put(cate.getCategroy(),cate);
                });
                Map<String,String> toSaveCateMap = new HashMap<>(category.size());
                category.forEach(cate ->{
                    toSaveCateMap.put(cate,cate);
                });
                cateMap.forEach((k,v) ->{
                    if(!toSaveCateMap.containsKey(k)){
                        v.setDeleted(YWStoreCate.IS_DELETED);
                        cateDAO.updateByPrimaryKeySelective(v,YWStoreCate.Column.deleted);
                    }else {
                        v.setDeleted(YWStoreCate.NOT_DELETED);
                        cateDAO.updateByPrimaryKeySelective(v,YWStoreCate.Column.deleted);
                    }
                    toSaveCateMap.remove(k);
                });
                toSaveCateMap.forEach((k,v) ->{
                    if(!cateMap.containsKey(k)){
                        cateDAO.insert(wrap(k,storeId,channelId));
                    }
                });
            }
        }

    }

    public List<YWStore> getAllStories(String channelId){
        YWStoreExample.Criteria criteria = YWStoreExample.newAndCreateCriteria()
                .andStatusEqualTo(1)
                .andDeletedEqualTo(YWStore.NOT_DELETED).andChannelIdEqualTo(channelId);
        return dao.selectByExample(criteria.example());
    }
}
